home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / winlib.lzh / WINLIB / COLORICN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-18  |  8.4 KB  |  277 lines

  1. /********************************************************************
  2.  *                                                                    *
  3.  *    Color icon manipulation and drawing routines                    *
  4.  *    by Markus Gutschke, modified by Ken Hollis                         *
  5.  *                                                                    *
  6.  *    Copyright (C) 1994, Bitgate Software, Clever Bits and Markus    *
  7.  *                        Gutschke                                    *
  8.  *    All rights reserved.                                            *
  9.  *                                                                    *
  10.  *    Note: These routines were documented, and are EXTREMELY            *
  11.  *    difficult to understand without having extensive knowledge of    *
  12.  *    VDI.  Do NOT attempt to modify these routines unless you        *
  13.  *    ABSOLUTELY know what you're doing.                                *
  14.  *                                                                    *
  15.  ********************************************************************
  16.  *                                                                    *
  17.  *    Update log:                                                        *
  18.  *        *NONE*                                                        *
  19.  *                                                                    *
  20.  ********************************************************************/
  21.  
  22. #include <stddef.h>
  23. #include <string.h>
  24. #include "winlib.h"
  25.  
  26. LOCAL int intersect(int  x1,int  y1,int  w1,int  h1,
  27.                     int  x2,int  y2,int  w2,int  h2,
  28.                     int *x3,int *y3,int *w3,int *h3)
  29. {
  30.     *x3    = max(x1,x2);
  31.     *y3    = max(y1,y2);
  32.     *w3    = min(x1+w1-1,x2+w2-1) - *x3 + 1;
  33.     *h3    = min(y1+h1-1,y2+h2-1) - *y3 + 1;
  34.     return ((*w3 > 0) && (*h3 > 0));
  35. }
  36.  
  37. void FixColIcon(ICONBLK *iconBlk,int planes,short *sData,
  38.                 short *sMask,short *dData,short *dMask,
  39.                 short *dtData,short *dtMask,short *cnvTab)
  40. {
  41.     static int colcnv1[]    = {0,1};
  42.     static int colcnv2[]    = {0,2,3,1};
  43.     static int colcnv3[]    = {0,2,3,6,4,7,5,1};
  44.     static int colcnv4[]    = {0,2,3,6,4,7,5,8,9,10,11,14,12,15,13,1};
  45.     static int *colcnv[4]    = {colcnv1,colcnv2,colcnv3,colcnv4};
  46.     static MFDB colIndex    = {0,0,0,0,0,0,0,0,0};
  47.     static int oldPlanes    = 0,xferMode = 0;
  48.     static short *oldCnvTabPtr = NULL,oldCnvTab[16];
  49.     long        bitPlaneSize = 2L * ((iconBlk->ib_wicon + 15) / 16L)*
  50.                                (long)iconBlk->ib_hicon;
  51.     MFDB        pixel,source,dest,tmpIndex;
  52.     unsigned    x,y,b,p,i,j,tPlanes;
  53.     int            vdiHandle,pxy[8],col[2];
  54.     short        ditherBits,curDither,*sPtr,*dPtr,*mskPtr,*tmpBuf;
  55.     int            bitMapSize,colTabSize;
  56.  
  57.     if (planes == 1) {
  58.         memmove(dMask,sMask,bitPlaneSize);
  59.         memmove(dData,sData,bitPlaneSize);
  60.         if (dtMask) {
  61.             memmove(dtMask,sMask,bitPlaneSize);
  62.             mskPtr = dMask;
  63.             sPtr   = dData;
  64.             dPtr   = dtData;
  65.             for (y = 0; y < iconBlk->ib_hicon; y++) {
  66.                 ditherBits = 0x5555 << (y & 1);
  67.                 for (x = (iconBlk->ib_wicon + 15) / 16; x--; ) {
  68.                     curDither = ditherBits & *mskPtr++;
  69.                     *dPtr++ = *sPtr++ | curDither;
  70.                 }
  71.             }
  72.         }
  73.         return;
  74.     }
  75.  
  76.     vdiHandle = VDIhandle;
  77.     memmove(dMask,sMask,bitPlaneSize);
  78.  
  79.     tPlanes                = planes < 8 && cnvTab != NULL ? 8 : planes;
  80.     source.fd_addr        = sData;
  81.     source.fd_w            = iconBlk->ib_wicon;
  82.     source.fd_h            = iconBlk->ib_hicon;
  83.     source.fd_wdwidth    = (iconBlk->ib_wicon + 15) / 16;
  84.     source.fd_stand        = 1;
  85.     source.fd_nplanes    = num_planes /* planes */ /***/;
  86.     source.fd_r1        =
  87.     source.fd_r2        =
  88.     source.fd_r3        = 0;
  89.     dest                = source;
  90.     dest.fd_addr        = dData;
  91.     dest.fd_stand        = 0;
  92.     dest.fd_nplanes        = num_planes;
  93.     bitMapSize            = num_planes * (((1 << tPlanes) + 15) & ~15) / 8;
  94.     colTabSize            = (int)sizeof(short) * (1 << tPlanes);
  95.  
  96.     tmpBuf = malloc(num_planes * bitPlaneSize * (dtMask ? 2 : 1));
  97.     if (colIndex.fd_addr == NULL || oldPlanes != tPlanes ||
  98.         oldCnvTabPtr != cnvTab ||
  99.         (cnvTab != NULL && memcmp(oldCnvTab,cnvTab,sizeof(oldCnvTab)))) {
  100.         if (colIndex.fd_addr != 0)
  101.             free(colIndex.fd_addr);
  102.     retry:
  103.         if ((colIndex.fd_addr = malloc(2 * max(bitMapSize,colTabSize)))==NULL) {
  104.             if (tmpBuf) {
  105.                 free(tmpBuf);
  106.                 tmpBuf = NULL;
  107.                 goto retry;
  108.             }
  109.  
  110.             memset(dData,0,(long)num_planes * bitPlaneSize);
  111.             memmove(dData,dMask,(long)bitPlaneSize);
  112.             vr_trnfm(vdiHandle,&source,&dest);
  113.             return;
  114.         }
  115.  
  116.         if (cnvTab != NULL)
  117.             memmove(oldCnvTab,cnvTab,sizeof(oldCnvTab));
  118.  
  119.         oldPlanes            = tPlanes;
  120.         oldCnvTabPtr        = cnvTab;
  121.         pixel.fd_addr        = "\xFF";
  122.         pixel.fd_w            =
  123.         pixel.fd_h            =
  124.         pixel.fd_wdwidth    =
  125.         pixel.fd_stand        =
  126.         pixel.fd_nplanes    = 1;
  127.         pixel.fd_r1            =
  128.         pixel.fd_r1            =
  129.         pixel.fd_r1            = 0;
  130.         colIndex.fd_w        = 1L << tPlanes;
  131.         colIndex.fd_h        = 1;
  132.         colIndex.fd_wdwidth    = (colIndex.fd_w+15)/16;
  133.         colIndex.fd_stand    = 0;
  134.         colIndex.fd_nplanes    = num_planes;
  135.         colIndex.fd_r1        =
  136.         colIndex.fd_r2        =
  137.         colIndex.fd_r3        = 0;
  138.  
  139.         for (i = (unsigned)(1L << tPlanes); i--;) {
  140.             pxy[0] = pxy[1] = pxy[2] = pxy[3] = pxy[5] = pxy[7] = 0;
  141.             pxy[4] = pxy[6] = (int)i;
  142.             col[0] = i; col[1] = 0;
  143.             vrt_cpyfm(vdiHandle,MD_REPLACE,pxy,&pixel,&colIndex,col);
  144.         }
  145.  
  146.         tmpIndex = colIndex;
  147.         memmove((char *)tmpIndex.fd_addr += bitMapSize,
  148.                 (char *)colIndex.fd_addr,bitMapSize);
  149.         colIndex.fd_stand = 1;
  150.         vr_trnfm(vdiHandle,&tmpIndex,&colIndex);
  151.  
  152.         for (i = 0, 
  153.             dPtr = (short *)colIndex.fd_addr +
  154.                    max(bitMapSize,colTabSize) / 2;
  155.             i < (unsigned)(1L << tPlanes); i++, dPtr++) {
  156.             *dPtr = 0;
  157.             for (j = num_planes, sPtr = (short*)colIndex.fd_addr + i / 16;
  158.                  j--; sPtr = (short *)((char *)sPtr+
  159.                                        (((1L << tPlanes) + 15) & ~15) / 8))
  160.                 *dPtr |= !!((*sPtr << (i % 16)) & 0x8000) << (num_planes - 1 - j);
  161.         }
  162.  
  163.         dPtr = (short *)colIndex.fd_addr;
  164.         sPtr = (short *)colIndex.fd_addr + max(bitMapSize,colTabSize) / 2;
  165.         p = planes >= 4 ? 4 : planes;
  166.         for (i = 1 << planes; i--; ) {
  167.             int j;
  168.             if (i < (1 << p) - 1)
  169.                 j = colcnv[p-1][i];
  170.             else if (i == (1 << planes) - 1)
  171.                 j = 1;
  172.             else
  173.                 j = i-1;
  174.  
  175.             dPtr[i] = cnvTab && j < 16 ? sPtr[cnvTab[j]] : sPtr[j];
  176.         }
  177.  
  178.         for (i = 1 << planes, xferMode = 0; i--;)
  179.             if (dPtr[i] != i) 
  180.                 if (xferMode != 1 && i == (1 << planes)-1 &&
  181.                     dPtr[i] == (1 << num_planes)-1)
  182.                     xferMode = 2;
  183.                 else
  184.                     xferMode = 1;
  185.     }
  186.  
  187.     switch (xferMode) {
  188.     case 0:
  189.         if (num_planes > planes)
  190.             memset((tmpBuf ? tmpBuf : dData) + planes * bitPlaneSize / 2L,0,
  191.                    (num_planes-planes) * bitPlaneSize);
  192.         memmove(tmpBuf ? tmpBuf : dData,sData,planes * bitPlaneSize);
  193.         break;
  194.  
  195.     case 1:
  196.         for (y = 0, sPtr = sData, dPtr = tmpBuf ? tmpBuf : dData; y < iconBlk->ib_hicon; y++) {
  197.             for (x = 0; x < iconBlk->ib_wicon; x += 16, sPtr++, dPtr++) {
  198.                 for (p = num_planes; p--; dPtr += bitPlaneSize / sizeof(short))
  199.                     *dPtr = 0;
  200.  
  201.                 dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short);
  202.  
  203.                 for (b = 1; b != 0; b <<= 1) {
  204.                     sPtr += (long)planes * (long)bitPlaneSize / sizeof(short);
  205.  
  206.                     for (p = 0, i = 0; p < planes; p++) {
  207.                         sPtr -= bitPlaneSize/sizeof(short);
  208.                         i = (i << 1) | !!(*sPtr & b);
  209.                     }
  210.  
  211.                     i = ((short *) colIndex.fd_addr)[i];
  212.                     for (p = 0; p < num_planes; p++, dPtr += bitPlaneSize / sizeof(short))
  213.                         if (i & (1 << p))
  214.                             *dPtr |= b;
  215.  
  216.                     dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short);
  217.                 }
  218.             }
  219.         }
  220.         break;
  221.  
  222.     case 2:
  223.         dPtr = tmpBuf ? tmpBuf : dData;
  224.         sPtr = sData;
  225.         for (y = 0; y < iconBlk->ib_hicon; y++) {
  226.             for (x = 0; x < iconBlk->ib_wicon; x += 16) {
  227.                 i = 0xFFFF;
  228.                 for (p = planes; p--; sPtr += bitPlaneSize / sizeof(short), dPtr += bitPlaneSize / sizeof(short))
  229.                     i &= *dPtr = *sPtr;
  230.  
  231.                 sPtr -= (long)planes * bitPlaneSize / sizeof(short) - 1;
  232.                 for (p = num_planes - planes; p--; dPtr += bitPlaneSize / sizeof(short))
  233.                     *dPtr = i;
  234.  
  235.                 dPtr -= (long)num_planes * bitPlaneSize / sizeof(short)-1;
  236.             }
  237.         }
  238.         break;
  239.     }
  240.  
  241.     if (dtMask) {
  242.         memmove(dtMask,sMask,bitPlaneSize);
  243.         mskPtr = dMask;
  244.         sPtr   = tmpBuf ? tmpBuf : dData;
  245.         dPtr   = tmpBuf ? tmpBuf + num_planes * bitPlaneSize / 2L : dtData;
  246.  
  247.         for (y = 0; y < iconBlk->ib_hicon; y++) {
  248.             ditherBits = 0x5555 << (y & 1);
  249.             for (x = (iconBlk->ib_wicon + 15) / 16; x--; ) {
  250.                 curDither = ditherBits & *mskPtr++;
  251.                 for (p = num_planes; p--; sPtr += bitPlaneSize/sizeof(short), dPtr += bitPlaneSize/sizeof(short))
  252.                         *dPtr = *sPtr | curDither;
  253.  
  254.                 sPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short)-1;
  255.                 dPtr -= (long)num_planes * (long)bitPlaneSize / sizeof(short)-1;
  256.             }
  257.         }
  258.  
  259.         source.fd_addr    = tmpBuf ? tmpBuf + num_planes * bitPlaneSize / 2L : dtData;
  260.         source.fd_nplanes = num_planes;
  261.         dest.fd_addr    = dtData;
  262.  
  263.         vr_trnfm(vdiHandle,&source,&dest);
  264.     }
  265.  
  266.     source.fd_addr        = tmpBuf ? tmpBuf : dData;
  267.     source.fd_nplanes    = num_planes;
  268.     dest.fd_addr        = dData;
  269.  
  270.     vr_trnfm(vdiHandle,&source,&dest);
  271.     if (tmpBuf)
  272.         free(tmpBuf);
  273.  
  274.     vsl_color(vdiHandle, 1);
  275.  
  276.     return;
  277. }